Skip to content

feat(projects): Load project stats with react query, remove ProjectsStatsStore#115463

Merged
scttcper merged 7 commits into
masterfrom
scttcper/project-stats-query-keys
May 15, 2026
Merged

feat(projects): Load project stats with react query, remove ProjectsStatsStore#115463
scttcper merged 7 commits into
masterfrom
scttcper/project-stats-query-keys

Conversation

@scttcper
Copy link
Copy Markdown
Member

@scttcper scttcper commented May 13, 2026

Kills the ProjectsStatsStore. Mostly used on the /projects/ page. Allows us to remove some types from the global project object that typically don't exist via the ProjectsStore.

View Interactive Review

Project cards were still going through the old Reflux stats store and mutating project-shaped data with endpoint-expanded stats fields.

Move the dashboard over to useAggregatedQueryKeys, keep stats separate from the base Project type, and let the project card read stats through the new hook.

Co-Authored-By: Codex <noreply@openai.com>
@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label May 13, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 13, 2026

📊 Type Coverage Diff

✅ No new type safety issues introduced. Coverage: 93.53%

Project cards could flash back to loading after being unmounted for a bit because the aggregate hook only reduced cached responses for the local ids it had already buffered.

Allow callers to synchronously read cached aggregate data for a specific id before queueing another request, so scrolling back to a project card keeps the stats around.

Co-Authored-By: Codex <noreply@openai.com>
};

export function ProjectStatsGraph({project, stats}: Props) {
stats = stats || project.stats || [];
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mutating props?

@scttcper scttcper changed the title ref(projects): Load dashboard stats with aggregated queries feat(projects): Load project stats with react query, remove ProjectsStatsStore May 13, 2026
The customer details test hits the projects endpoint with statsPeriod=30d, but the shared getsentry project fixture no longer carries stats by default.

Keep stats out of the base fixture and add the endpoint-expanded field at the mock response instead.

Co-Authored-By: Codex <noreply@openai.com>
@scttcper scttcper marked this pull request as ready for review May 13, 2026 16:16
@scttcper scttcper requested review from a team as code owners May 13, 2026 16:16
Comment thread static/app/views/projectsDashboard/projectCard.tsx
Comment thread static/app/utils/api/useAggregatedQueryKeys.tsx
],
});

const {result, unmount} = renderHook(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you might want like renderHookWithProviders

and damnit, now i want to go back over all that again and merge it this time.

Comment on lines +26 to +28
afterEach(() => {
MockApiClient.clearMockResponses();
});
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this happenes automatically eh?

Comment on lines +58 to +59
const projectStats = getProjectStats(simpleProject);
const {stats, transactionStats, sessionStats, latestDeploys} = projectStats;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const projectStats = getProjectStats(simpleProject);
const {stats, transactionStats, sessionStats, latestDeploys} = projectStats;
const {stats, transactionStats, sessionStats, latestDeploys} = getProjectStats(simpleProject);

fighting the bots here...

Comment on lines +108 to +127
const getOne = useCallback(
(project: Project): ProjectStatsData => {
const initialStats = getStatsData(project);
const cachedStats = projectStats.read([project.id])?.[project.id];

if (cachedStats && hasStats(cachedStats, hasPerformance)) {
return cachedStats;
}

if (!hasStats(initialStats, hasPerformance)) {
projectStats.buffer([project.id]);
}

return projectStats.data?.[project.id] ?? initialStats;
},
[hasPerformance, projectStats]
);

return useMemo(() => ({getOne}), [getOne]);
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be something to port into feedback

over there we have:

  const getOne = useCallback(
    (id: string) => {
      cache.buffer([id]);

      return cache.data?.[id];
    },
    [cache]
  );

just reading from the buffer (which is the last queued set of ids). What we could do in feedback is call cache.read([id]) first, to get existing data, and then call buffer after if needed.

remove the extra mock cleanup, simplify the remount test, and apply the small destructuring nit from review.

Co-Authored-By: Codex GPT-5 <noreply@openai.com>
@scttcper scttcper merged commit f379a30 into master May 15, 2026
70 checks passed
@scttcper scttcper deleted the scttcper/project-stats-query-keys branch May 15, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants